#include "../src/sink.hpp"

// 日志落地扩展---以时间作为滚动文件的条件
// 1、以时间进行文件滚动，实际上是以时间段进行滚动
//   实现思想：
//       1、以时间进行文件滚动，实际上是以时间段进行滚动
//       2、每个时间段内，日志都输出到同一个文件中
//       3、当时间段到了，就会滚动文件，生成一个新的文件，继续输出日志

namespace extend
{
    enum class TimeGap
    {
        Day,
        Hour,
        Minute,
        Second
    };
    class RollByTimeSink : public mylog::LogSink
    {
    public:
        RollByTimeSink(const std::string &basename, TimeGap gap_size)
            : _basename(basename)
        {
            switch (gap_size)
            {
            case TimeGap::Day:
                _gap_size = 24 * 60 * 60;
                break;
            case TimeGap::Hour:
                _gap_size = 60 * 60;
                break;
            case TimeGap::Minute:
                _gap_size = 60;
                break;
            case TimeGap::Second:
                _gap_size = 1;
                break;
            default:
                _gap_size = 1;
            }

            _cur_gap = mylog::util::Date::now() / _gap_size;
            std::string filename = createNewFile();
            mylog::util::File::createDirectory(mylog::util::File::path(filename));
            _ofs.open(filename, std::ios::binary | std::ios::app);
            assert(_ofs.is_open());
        }

        virtual void log(const char *data, size_t len) override
        {
            time_t cur = mylog::util::Date::now();
            if ((cur / _gap_size) != _cur_gap)
            {
                _ofs.close();
                _cur_gap = cur / _gap_size;
                std::string filename = createNewFile();
                _ofs.open(filename, std::ios::binary | std::ios::app);
                assert(_ofs.is_open());
            }
            _ofs.write(data, len);
            assert(_ofs.good());
        }

    private:
        std::string createNewFile()
        {
            // 获取系统时间，用来构造文件扩展名
            time_t t = mylog::util::Date::now();
            struct tm lt;
            localtime_r(&t, &lt);
            std::stringstream filename;
            filename << _basename << "-";
            filename << lt.tm_year + 1900;
            filename << lt.tm_mon + 1;
            filename << lt.tm_mday;
            filename << lt.tm_hour;
            filename << lt.tm_min;
            filename << lt.tm_sec;
            filename << ".log";
            return filename.str();
        }

    private:
        std::string _basename;
        std::ofstream _ofs;
        size_t _cur_gap;  // 当前所在的时间段间隔（秒）
        size_t _gap_size; // 时间段大小（秒）
    };
}